package hotel.callback.oversea.task;

import hotel.callback.oversea.config.service.RedisService;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.MeituanConstants;
import hotel.base.oversea.utils.DateUtil;
import hotel.base.oversea.utils.GsonUtils;
import hotel.base.oversea.utils.Result;
import hotel.base.oversea.utils.StringUtil;
import hotel.base.oversea.vo.BatchPushRoomDatasVo;
import hotel.base.oversea.vo.RoomDataEntityVO;
import hotel.base.oversea.vo.RoomStatusInventory;
import hotel.base.oversea.vo.meituan.request.goods.MtHotelGoodsStatusDetailStateVo;
import hotel.base.oversea.vo.meituan.request.goods.MtHotelGoodsStatusDetailVo;
import hotel.callback.oversea.service.MtHotelGoodsService;
import hotel.callback.oversea.vo.meituan.MtHotelGoodsStatusVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;


@Slf4j
@Component
public class MeituanPartTimeDealStatusVSecTask {
    private String timestamp = "mcohgdt"+String.valueOf(System.currentTimeMillis());
    @Autowired
    private RedisService redisService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MtHotelGoodsService mtHotelGoodsService;
    @Async("threadPoolSt")
    public void executeDealQueryStatusData(List<String> list){
        log.info("MeituanPartTimeQueryStatusTask {} >>>>>>>>> 异步线程 解析房态数据task  开始执行时间：{}",timestamp, DateUtil.getNowTime());
        if(!ObjectUtils.isEmpty(list)){
            for (int i = 0; i < list.size(); i++) {
                String s = list.get(i);
                String[] array = s.split("_hhb");
                String responseData = array[0];
                String hotelId = array[1];
                String start = array[2];
                String end = array[3];
                deal(responseData,hotelId,start,end);
            }
        }
        //log.info("MeituanPartTimeQueryStatusTask {} >>>>>>>>> 异步线程 解析房态数据task  执行结束时间：{}",timestamp,DateUtil.getNowTime());

    }

    /**
     * 主动查询房态接口（包含库存接口）
     */
    private void deal(String responseData,String hotelId,String startDateRoomStatus,String endDate) {
        Date nowDate = new Date();
        String nowHourStr = DateUtil.formatDate(nowDate,"HH");
        String yestoday = DateUtil.formatDate(DateUtil.addDay(nowDate,-1),"yyyy-MM-dd");
        String today = DateUtil.formatDate(nowDate,"yyyy-MM-dd");
        Map<Integer,Integer> valiSaleAllGoodsMap = new HashMap();//key = goodsId,vallue=goodsId  组装集合放置所有校验后有效的产品（因为存在某产品无价格变化但有状态变化需处理）
        Map<String, MtHotelGoodsStatusDetailVo> allChangeGoodsAboutStatusMap = new HashMap<>();//当前酒店所有的产品的房态信息  key = goodsId,value=status对象信息包含status集合
        Result<Object> statusResponse = mtHotelGoodsService.checkMtStatusResultData(responseData);
        //log.info("MeituanPartTimeQueryStatusTask hotelId={},statusResponse={}",hotelId, GsonUtils.GsonString(statusResponse));
        log.info("MeituanPartTimeQueryStatusTask deal hotelId={}",hotelId);
        if(null != statusResponse && statusResponse.getCode()== CommonConstants.SUCCESS && null != statusResponse.getData()){
            Long thisTimestamp = System.currentTimeMillis();
            String thisTimestampApi = StringUtil.getTimestampRandom(thisTimestamp).toString()+String.valueOf(hotelId).substring(0,4)+String.valueOf(21);

            MtHotelGoodsStatusVo mtHotelGoodsStatusVo = (MtHotelGoodsStatusVo) statusResponse.getData();
            List<MtHotelGoodsStatusDetailVo> thisHotelAllGoodsStatuses = mtHotelGoodsStatusVo.getGoodsStatuses();
            Integer compare = 0;
            if(null != thisHotelAllGoodsStatuses && thisHotelAllGoodsStatuses.size()>0){
                for (MtHotelGoodsStatusDetailVo v:thisHotelAllGoodsStatuses){
                    //判断该产品是否为我们的上架产品，是才需要查询比对价格
                    String existSale = null;

                    existSale = (String)redisService.hmGet(CommonConstants.SWITCH_SELLING_THE_HOUSE_TYPE,hotelId+"_"+v.getGoodsId());
                    if(!ObjectUtils.isEmpty(existSale)){
                        //log.info("MeituanPartTimeQueryStatusTask 进入第二版 判断上架产品：thisGoodsId={},existSale={}",v.getGoodsId(),existSale);
                    }else{
                        existSale = (String)redisService.get(CommonConstants.SWITCH_SELLING_THE_HOUSE_TYPE+hotelId+"_"+v.getGoodsId());
                        //log.info("MeituanPartTimeQueryStatusTask 进入第一版 判断上架产品：thisGoodsId={},existSale={}",v.getGoodsId(),existSale);
                    }

                    if(null != existSale){
                        log.info("MeituanPartTimeQueryStatusTask deal hotelId={},goodsId={}",hotelId,v.getGoodsId());
                        //log.info("MeituanPartTimeQueryStatusTask 匹配到 existSale={}",existSale);
                        //重构 对象  v
                        //判断存在变化的产品的 日期房态
                        List<MtHotelGoodsStatusDetailStateVo>  thisGoodsAllDateState = v.getGoodsStatuses();
                        if(null != thisGoodsAllDateState && thisGoodsAllDateState.size()>0){
                            Integer goodsId = v.getGoodsId();
                            boolean notHistoryExisChange = true;
                            if(notHistoryExisChange){//不是推送过的 存在了变化

                                List<MtHotelGoodsStatusDetailStateVo>  thisGoodsMonthChangeDateStateNew = new ArrayList<>();
                                if(null != thisGoodsAllDateState){

                                    log.info("checkMtGoodsChange酒店={},thisGoodsAllDateState={}",hotelId,thisGoodsAllDateState.size());

                                    for (MtHotelGoodsStatusDetailStateVo s:thisGoodsAllDateState){
                                        Integer state = s.getStatus();
                                        String date = s.getDate();

                                        //5天变成售卖4天
                                        String closeThisDateRedis = (String)redisService.get("vip_close_this_date");//yyyy-MM-dd
                                        if(!ObjectUtils.isEmpty(closeThisDateRedis)){
                                            if(closeThisDateRedis.equals(date)){
                                                log.info("SECSTATUS VIP 减少天售卖，从后递减 hotelId={},goodsId={},closeThisDateRedis={},date={},state={}",hotelId,goodsId,closeThisDateRedis,date,state);
                                                state = 0;
                                            }
                                        }

                                        Boolean isChange = mtHotelGoodsService.checkMtGoodsChange(today,nowHourStr,yestoday,hotelId,goodsId,date,state,"room_status","2",null,thisTimestampApi);
                                        if(isChange){
                                            //log.info("校验返回存在房态变化{}，一个产品一个日期价格发生变化房态产品信息为{}",timestamp,thisKey+"_"+date+"_"+state+",");
                                            //该产品该日期的状态发送改变，重构数据
                                            thisGoodsMonthChangeDateStateNew.add(s);

                                            log.info("thisTimestampApi={} checkMtGoodsChange通过了校验酒店={},goodsId={}",thisTimestampApi,hotelId,goodsId);

                                            if(BigDecimal.valueOf(state).compareTo(BigDecimal.valueOf(1))!=0){
                                                //log.info("主动房态不可预订推送thisHotelCompare=1hotelId={},goodsId={},date={}",hotelId,goodsId,date);
                                                compare = 1;
                                            }

                                        }else{
                                            log.info("checkMtGoodsChange没有通过校验酒店={},goodsId={}",hotelId,goodsId);
                                        }

                                    }
                                    //log.info("///////////////////////主动查询-美团接口-校验酒店产品 {} 一个产品所有日期房态有变化产品房态thisGoodsMonthChangeDateStateNewhotelId={},thisGoodsMonthChangeDateStateNew={}",timestamp,hotelId,thisGoodsMonthChangeDateStateNew);
                                    if(thisGoodsMonthChangeDateStateNew.size()>0){
                                        //遍历完当前产品的31天房态,存在变动
                                        v.setGoodsStatuses(thisGoodsMonthChangeDateStateNew);//重构数据
                                        //log.info("///////////////////////主动查询-美团接口-校验酒店产品 {} 一个产品的所有日期房态存在变化产品房态追加hotelId={},thisGoodsMonthChangeDateStateNewToallChangeGoodsAboutStatusMap={}",timestamp,hotelId,v);
                                        allChangeGoodsAboutStatusMap.put(String.valueOf(v.getGoodsId()),v);
                                        valiSaleAllGoodsMap.put(v.getGoodsId(),v.getGoodsId());

                                    }
                                }
                            }else{
                                //log.info("statusCheckThisHotel酒店该产品未来30天datajson串与上一次一样当前不进入房态变化校验酒店={}",hotelId);
                            }
                        }
                    }
                }
            }else{
                log.error("该酒店查询不到房态信息酒店id={},statusResponse={},startDateRoomStatus={},enddate={}",hotelId, GsonUtils.GsonString(statusResponse),startDateRoomStatus,endDate);
            }
            int sizeState = allChangeGoodsAboutStatusMap == null ? 0:allChangeGoodsAboutStatusMap.size();
            if(sizeState>0){
                //log.info("该酒店存在房态房态需要推送酒店={},{}",hotelId,timestamp);
                log.info("///////////////////////主动查询-美团接口-校验酒店产品 {} 存在数据完成该酒店所有产品所有日期房态校对hotelId={},allChangeGoodsAboutStatusMap={}",timestamp,hotelId,allChangeGoodsAboutStatusMap);
                //异步线程   更新保存  房态 库表数据  多个产品 多组一个月日期房态
                //meituanSaveUpdateGoodsStatusTableTask.executeSaveUpdateGoodsStatusTable(allChangeGoodsAboutStatusMap,hotelId);  2020-10-12 暂时注释
                //version 20200828 构建携程接口参数，保存变化的数据到缓存队列，
                buildStatusChangeDataToSwitchsRedis(hotelId,valiSaleAllGoodsMap,allChangeGoodsAboutStatusMap,compare,thisTimestampApi);//allChangeGoodsAboutDatePriceMap,allChangeGoodsAboutStatusMap);
            }else{
                log.info("该酒店没有房态房态需要推送酒店={},{}",hotelId,timestamp);

            }

        }


    }

    private void buildStatusChangeDataToSwitchsRedis(String hotelId,Map<Integer,Integer> valiSaleAllGoodsMap,
                                                     Map<String,MtHotelGoodsStatusDetailVo> allChangeGoodsAboutStatusMap,Integer compare,String thisTimestampApi) {
        //log.info("{} 进入方法开始执行buildStatusChangeDataToSwitchsRedis,push到缓存队列存在变动的房态产品，" +
        //"主动变动房态入参有效产品集合为{},主动变动房态入参酒店为{},主动变动房态入参房态数据为{} ",timestamp,GsonUtils.GsonString(valiSaleAllGoodsMap),hotelId,GsonUtils.GsonString(allChangeGoodsAboutStatusMap));
        List<RoomDataEntityVO> oneHotelAboutAllChangeGoodsVoSwitchsApi = new ArrayList<>();//酒店vo-所有变化产品listVo，酒店vo所有变化了的产品信息
        BatchPushRoomDatasVo oneHotelVoSwitchsApi = null;//构建携程接口酒店vo

        for (Map.Entry entry:valiSaleAllGoodsMap.entrySet()){
            //遍历所有变化的产品
            String goodsId = String.valueOf(entry.getKey());

            //重构携程接口对象，构建一个产品vo，加入产品volist
            RoomDataEntityVO oneChangeGoodsSwitchsApi = new RoomDataEntityVO();
            oneChangeGoodsSwitchsApi.setGoodId(Integer.valueOf(goodsId));//当前产品id

            //构建接口数据结构：一个产品的房态 数据结构
            List<RoomStatusInventory> thisGoodsRoomStatusInventoryList = null;
            MtHotelGoodsStatusDetailVo thisGoodsDateStatusData = allChangeGoodsAboutStatusMap.get(goodsId);
            if(null != thisGoodsDateStatusData){
                thisGoodsRoomStatusInventoryList = new ArrayList<>();
                for (MtHotelGoodsStatusDetailStateVo status:thisGoodsDateStatusData.getGoodsStatuses()){
                    RoomStatusInventory roomStatusInventory = new RoomStatusInventory();
                    roomStatusInventory.setDate(status.getDate());
                    roomStatusInventory.setGoodStatus(status.getStatus());
                    thisGoodsRoomStatusInventoryList.add(roomStatusInventory);
                }
            }
            oneChangeGoodsSwitchsApi.setGoodInventory(1);//allValiSaleGoodsAboutValiInventoryMap.get(goodsId));//当前产品的库存（0或1表示未来一个月有或无）
            oneChangeGoodsSwitchsApi.setRoomStatusInventorys(thisGoodsRoomStatusInventoryList);//当前产品的房态集合（一个月）

            oneHotelAboutAllChangeGoodsVoSwitchsApi.add(oneChangeGoodsSwitchsApi);//追加入携程vo酒店所有变化产品集合中
        }
        //最终返回酒店vo
        if(null != oneHotelAboutAllChangeGoodsVoSwitchsApi && oneHotelAboutAllChangeGoodsVoSwitchsApi.size()>0){

            oneHotelVoSwitchsApi = new BatchPushRoomDatasVo();
            oneHotelVoSwitchsApi.setMtHotelId(Integer.valueOf(hotelId));
            oneHotelVoSwitchsApi.setCompare(compare);
            oneHotelVoSwitchsApi.setTimestamp(thisTimestampApi);
            oneHotelVoSwitchsApi.setRoomDataEntityList(oneHotelAboutAllChangeGoodsVoSwitchsApi);
            //log.info("{} push到缓存队列存在变动的房态产品，主动变动房态时间戳为{},主动变动房态酒店为{},主动变动房态推送数据为{} ",timestamp,thisTimestampApi,hotelId,GsonUtils.GsonString(oneHotelVoSwitchsApi));
            //oneHotelVoSwitchsApi json字符串 加入缓存队列中
            //log.info("推送到携程队列statusjoboneHotelVoSwitchsApi房态 : "+GsonUtils.GsonString(oneHotelVoSwitchsApi));
            pushQueueRpPriceAndStatus(oneHotelVoSwitchsApi);

        }
    }
    public void pushQueueRpPriceAndStatus(BatchPushRoomDatasVo oneHotelVoSwitchsApi){

        //1、加入队列，推给携程
        redisTemplate.opsForList().leftPush(MeituanConstants.REDIS_CHANGE_GOODS_DATA_MANY_HOTEL,GsonUtils.GsonString(oneHotelVoSwitchsApi));

    }

}
